////////////////////////////////////////////////////////////////////////////////
//
//  Copyright (c) 2011 Gabriel Montagné Láscaris-Comneno and Alberto
//  Brealey-Guzmán.
//
//  Permission is hereby granted, free of charge, to any person obtaining a
//  copy of this software and associated documentation files (the "Software"),
//  to deal in the Software without restriction, including without limitation
//  the rights to use, copy, modify, merge, publish, distribute, sublicense,
//  and/or sell copies of the Software, and to permit persons to whom the
//  Software is furnished to do so, subject to the following conditions:
//
//  The above copyright notice and this permission notice shall be included in
//  all copies or substantial portions of the Software.
//
//  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
//  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
//  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
//  THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
//  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
//  FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
//  DEALINGS IN THE SOFTWARE.
//
////////////////////////////////////////////////////////////////////////////////

package com.rojored.preloaders
{

import flash.display.Sprite;
import flash.events.Event;
import flash.events.ProgressEvent;
import mx.events.FlexEvent;
import mx.events.RSLEvent;
import mx.preloaders.IPreloaderDisplay;

/**
 *  Base preloader class to comply with the <code>IPreloaderDisplay</code>
 *  interface.
 *
 *  <p>The <code>PreloaderBase</code> class does not display any kind of
 *  progress. The programmer must extend the class and provide handlers for
 *  the many progress and completion events to give feedback to the user about
 *  the bootup and loading of the application.</p>
 */
public class PreloaderBase extends Sprite implements IPreloaderDisplay
{

    //--------------------------------------------------------------------------
    //
    //  Constructor
    //
    //--------------------------------------------------------------------------

    /**
     * Constructor
     */
    public function PreloaderBase()
    {
        super();
    }

    //--------------------------------------------------------------------------
    //
    //  Properties
    //
    //--------------------------------------------------------------------------

    //----------------------------------
    //  backgroundAlpha
    //----------------------------------

    private var _backgroundAlpha:Number;

    /**
     *  Alpha level of the background image or background color.
     */
    public function get backgroundAlpha():Number
    {
        return _backgroundAlpha;
    }

    public function set backgroundAlpha(value:Number):void
    {
        _backgroundAlpha = value;
    }

    //----------------------------------
    //  backgroundColor
    //----------------------------------

    private var _backgroundColor:uint;

    /**
     *  Background color of the preloader display.
     */
    public function get backgroundColor():uint
    {
        return _backgroundColor;
    }

    public function set backgroundColor(value:uint):void
    {
        _backgroundColor = value;
    }

    //----------------------------------
    //  backgroundImage
    //----------------------------------

    private var _backgroundImage:Object;

    /**
     *  Background image of the preloader display.
     */
    public function get backgroundImage():Object
    {
        return _backgroundImage;
    }

    public function set backgroundImage(value:Object):void
    {
        _backgroundImage = value;
    }

    //----------------------------------
    //  backgroundSize
    //----------------------------------

    private var _backgroundSize:String;

    /**
     *  Percentage scale of the background image.
     */
    public function get backgroundSize():String
    {
        return _backgroundSize;
    }

    public function set backgroundSize(value:String):void
    {
        _backgroundSize = value;
    }

    //----------------------------------
    //  preloader
    //----------------------------------

    private var _preloader:Sprite;

    /**
     *  <code>Preloader</code> instance that dispatches the progress and
     *  various bootup stage completion events.
     */
    public function set preloader(value:Sprite):void
    {
        _preloader = value;
        addPreloaderEventListeners();
    }

    //----------------------------------
    //  stageHeight
    //----------------------------------

    private var _stageHeight:Number;

    /**
     *  Height of the stage, passed by the <code>Preloader</code> instance.
     */
    public function get stageHeight():Number
    {
        return _stageHeight;
    }

    public function set stageHeight(value:Number):void
    {
        _stageHeight = value;
    }

    //----------------------------------
    //  stageWidth
    //----------------------------------

    private var _stageWidth:Number;

    /**
     *  Width of the stage, passed by the <code>Preloader</code> instance.
     */
    public function get stageWidth():Number
    {
        return _stageWidth;
    }

    public function set stageWidth(value:Number):void
    {
        _stageWidth = value;
    }

    //--------------------------------------------------------------------------
    //
    //  Methods
    //
    //--------------------------------------------------------------------------

    /**
     *  Method called by the <code>Preloader</code> instance when adding the
     *  preloader display as a child.
     *
     *  <p>When the <code>initialize</code> method is called the
     *  <code>stageWidth</code> and <code>stageHeight</code> values are known.
     *  The preloader display can then be drawn for the first time. The
     *  <code>stage</code> property is defined at this point.</p>
     */
    public function initialize():void
    {
    }

    /**
     *  @private
     */
    private function addPreloaderEventListeners():void
    {
        if (!_preloader)
            return;

        _preloader.addEventListener(Event.COMPLETE, completeHandler);
        _preloader.addEventListener(
            FlexEvent.INIT_COMPLETE,
            initCompleteHandler
        );
        _preloader.addEventListener(
            FlexEvent.INIT_PROGRESS,
            initProgressHandler
        );
        _preloader.addEventListener(ProgressEvent.PROGRESS, progressHandler);
        _preloader.addEventListener(
            RSLEvent.RSL_COMPLETE,
            rslCompleteHandler
        );
        _preloader.addEventListener(RSLEvent.RSL_ERROR, rslErrorHandler);
        _preloader.addEventListener(
            RSLEvent.RSL_PROGRESS,
            rslProgressHandler
        );
    }

    /**
     *  @private
     */
    private function removePreloaderEventListeners():void
    {
        if (!_preloader)
            return;

        _preloader.removeEventListener(Event.COMPLETE, completeHandler);
        _preloader.removeEventListener(
            FlexEvent.INIT_COMPLETE,
            initCompleteHandler
        );
        _preloader.removeEventListener(
            FlexEvent.INIT_PROGRESS,
            initProgressHandler
        );
        _preloader.removeEventListener(ProgressEvent.PROGRESS, progressHandler);
        _preloader.removeEventListener(
            RSLEvent.RSL_COMPLETE,
            rslCompleteHandler
        );
        _preloader.removeEventListener(RSLEvent.RSL_ERROR, rslErrorHandler);
        _preloader.removeEventListener(
            RSLEvent.RSL_PROGRESS,
            rslProgressHandler
        );
    }

    //--------------------------------------------------------------------------
    //
    //  Event handlers
    //
    //--------------------------------------------------------------------------

    /**
     *  Event handler for the <code>Event.COMPLETE</code> event.
     *
     *  <p>The <code>complete</code> event is dispatched by the
     *  <code>mx.preloaders.Preloader</code> instance when the Flex
     *  application has been loaded.</p>
     */
    protected function completeHandler(event:Event):void
    {
    }

    /**
     *  Event handler for the <code>FlexEvent.INIT_COMPLETE</code> event.
     *
     *  <p>The <code>initComplete</code> event is dispatched when the Flex
     *  application has finished its initialization phase. It is at this point
     *  that the application preloader display can be removed from the
     *  stage. The base implementation dispatches a <code>complete</code>
     *  event, so that the system manager removes the preloader display.</p>
     */
    protected function initCompleteHandler(event:FlexEvent):void
    {
        removePreloaderEventListeners();
        dispatchEvent(new Event(Event.COMPLETE));
    }

    /**
     *  Event handler for the <code>FlexEvent.INIT_PROGRESS</code> event.
     *
     *  <p>The <code>initProgress</code> event is dispatched every time the
     *  Flex application completes one of its live cycle phases.</p>
     */
    protected function initProgressHandler(event:FlexEvent):void
    {
    }

    /**
     *  Event handler for the <code>ProgressEvent.PROGRESS</code> event.
     *
     *  <p>The <code>progress</code> event is dispatched by the
     *  <code>mx.preloaders.Preloader</code> instance each time it receives
     *  data while downloading the Flex application.</p>
     */
    protected function progressHandler(event:ProgressEvent):void
    {
    }

    /**
     *  Event handler for the <code>RSLEvent.RSL_COMPLETE</code> event.
     *
     *  <p>The <code>rslComplete</code> event is dispatched every time an RSL
     *  finishes loading.</p>
     */
    protected function rslCompleteHandler(event:RSLEvent):void
    {
    }

    /**
     *  Event handler for the <code>RSLEvent.RSL_ERROR</code> event.
     *
     *  <p>The <code>rslError</code> event is dispatched by the preloader when
     *  there is an error loading one of the RSLs.</p>
     */
    protected function rslErrorHandler(event:RSLEvent):void
    {
    }

    /**
     *  Event handler for the <code>RSLEvent.RSL_PROGRESS</code> event.
     *
     *  <p>The <code>rslProgress</code> event is dispatched by the
     *  <code>mx.preloaders.Preloader</code> instance each time it receives
     *  data while loading one of the RSLs.</p>
     */
    protected function rslProgressHandler(event:RSLEvent):void
    {
    }

}
}
